home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 299_01 / mel.h < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-28  |  17.5 KB  |  503 lines

  1. /*
  2. ------------------------------------------------------------------------
  3. filename: mel.h
  4. author: g. m. crews
  5. creation date: 25-Jul-1988
  6. date of last revision: 19-Jul-1989
  7.  
  8. the following defines the input and output interface (called "dictionaries") 
  9. between MEL (a generic metalanguage processor) and the engineering analysis 
  10. program it is being used for. (see files mel.doc and mel.c for more
  11. information.)
  12.  
  13. the idea is to use "descriptors" (english-like strings) to make i/o more
  14. readable to an analysis program user or checker. the dictionaries define the
  15. "meanings" of the tokens in the string.
  16.  
  17. the following data objects form the interface:
  18.  
  19.     input:
  20.  
  21.     char meli_descriptor_string[]    input descriptor string
  22.     meli_file(...)            interpret data from text file
  23.     meli(...)            interpret data from above string
  24.     meli_descrip_type(...)        get descriptor type
  25.     meli_num_params(...)        get number parameters read
  26.     meli_param(...)         get value of particular parameter
  27.     meli_data(...)            get parameter data
  28.  
  29.     output:
  30.  
  31.     char melo_descriptor_string[]    output descriptor string
  32.     melo_init(...)            prepare to output descriptor
  33.     melo_data(...)            put parameter data
  34.     melo(...)            translate data to above string
  35.     melo_file(...)            translate and send to text file
  36.  
  37.     errors:
  38.  
  39.     struct {...} mel_err        i/o error description
  40.  
  41.  
  42. development and testing of any particular set of dictionaries may be 
  43. facilitated with a debugging program called test_mel.  for more information, 
  44. see the file test_mel.c. 
  45.  
  46. NOTE THAT THIS FILE MUST BE CUSTOMIZED FOR EACH TARGET APPLICATION PROGRAM.  
  47. APPLICATION DEVELOPERS SHOULD SEARCH FOR THE WORD "CUSTOMIZED" FOR THE 
  48. LOCATIONS OF NUMBERS AND OTHER DATA THAT NEED TO CHANGE TO REFLECT 
  49. REQUIREMENTS OF THEIR OWN PARTICULAR APPLICATION PROGRAM.
  50.  
  51. THE PARTICULAR DICTIONARIES CURRENTLY DEFINED ARE SIMPLY A TEST FOR
  52. ILLUSTRATIVE PURPOSES.    INPUT AND OUTPUT DICTIONARIES ARE IDENTICAL AND LOOK
  53. LIKE:
  54.  
  55.     program_data,
  56.     program = 'sss',
  57.     date = 'sss',
  58.     input_filename = 'sss',
  59.     output_filename = 'sss',
  60.     errors_filename = 'sss',
  61.     label = 'sss';
  62.     program_options,
  63.     output_format = 'sss';         "verbose or terse"
  64.     message,
  65.     code = nnn,
  66.     text = 'sss';
  67.     end_of_data;
  68.  
  69. (NOTE THAT nnn STANDS FOR A NUMBER AND 'sss' STANDS FOR A STRING.)
  70.  
  71. file content: the "public" interface is listed first, followed by the 
  72. "private" interface. application programmers should treat MEL as a "black box" 
  73. and thus only use the "public" definitions.  (note however that manifest
  74. constants, etc., in the "private" area will have to be customized.)
  75.  
  76. nomemclature: In the following, "meli" is used to label input terms, "melo"
  77. is used to label output terms, and "mel" is used for terms that may apply
  78. to either input or output.
  79.  
  80. global conditional complilation flags (see mel.doc for more information on
  81. these flags and when to use them) are used to control data hiding and maintain
  82. object oriented approach used for MEL:
  83.  
  84.     MEL_INPUT     -  define this flag when you wish to use the MEL input object
  85.             for your application programs.
  86.  
  87.     MEL_OUTPUT     -  define this flag when you wish to use MEL for output.
  88.  
  89.     MEL_PRIVATE  -  users normally should not define this flag when including
  90.             mel.h in their application program files. it is used
  91.             to define "private" data structures, etc., for internal  
  92.             MEL routines (see mel.c).                        
  93.  
  94.     MEL_INIT     -  developers should also not define this flag for the same
  95.             reasons as above.
  96. ------------------------------------------------------------------------
  97. */
  98.  
  99. /*
  100. ------------------------------------------------------------------------
  101. "public" declarations:
  102. ------------------------------------------------------------------------
  103. */
  104.  
  105. /* if using MEL for input, then must define the MEL input data object: */
  106. #ifdef MEL_INPUT
  107.  
  108. /* firstly, define input constants (all must be CUSTOMIZED): */
  109.  
  110. #define MELI_MAX_DESCRIP_STR_LEN 256
  111.     /* maximum number of characters in any input descriptor string. */
  112. #define MELI_MAX_PARAMS 6
  113.     /* maximum number of parameters for any descriptor (min = 1). */
  114. #define MELI_MAX_PARAM_STR_LEN 80
  115. #define MELI_MAX_PARAM_ARRAY_STR_LEN 1
  116.     /* largest allowable parameter string lengths (min = 1) */
  117. #define MELI_MAX_PARAM_INT_ARRAY_LEN 1
  118. #define MELI_MAX_PARAM_REAL_ARRAY_LEN 1
  119. #define MELI_MAX_PARAM_STR_ARRAY_LEN 1
  120.     /* maximum number of elements in parameter data arrays (min = 1). */
  121. #define MELI_UNITS_STR_LEN 80
  122.     /* maximum length of units associated with any param (min = 1) */
  123.  
  124. /* secondly, define input data structures: */
  125.  
  126. union meli_param_data {
  127.     int integer;
  128.     double real;
  129.     char string[MELI_MAX_PARAM_STR_LEN+1];
  130.     int integer_array[MELI_MAX_PARAM_INT_ARRAY_LEN];
  131.     double real_array[MELI_MAX_PARAM_REAL_ARRAY_LEN];
  132.     char string_array[MELI_MAX_PARAM_STR_ARRAY_LEN]
  133.              [MELI_MAX_PARAM_ARRAY_STR_LEN+1];
  134. };
  135. /* this is used for input parameter data. it may either be an integer,
  136.    real, string, array of integers, array of reals, or an array of
  137.    strings. (to save space a union was used.) */
  138.  
  139. /* thirdly, define input variables: */
  140.  
  141. char meli_descriptor_string[MELI_MAX_DESCRIP_STR_LEN+1];
  142.     /* global storage for the input descriptor string. */
  143.  
  144. /* lastly, define input functions (typically they return 0 if no error
  145.    encountered, else some nonzero error code): */
  146.  
  147. int meli_file(FILE *meli_file_handle);
  148.     /* read a descriptor string from the input stream and call meli().
  149.        also, put copy of string read into meli_descriptor_string. */
  150. int meli(void);
  151.     /* translate meli_descriptor_string and put information into a private
  152.        data structure (meli_datum). */
  153. char *meli_descrip_type(void);
  154.     /* return pointer to name of type of descriptor read by meli(). */
  155. int meli_num_params(void);
  156.     /* return number of parameters read by meli(). */
  157. int meli_param(int param_num, char *param, union meli_param_data *data,
  158.     char *units, int *array_len, int *unknown_flag);
  159.     /* fill arguement list with param_num'th parameter read by meli().
  160.        (start with param_num = 0.) */
  161. int meli_data(char *param, union meli_param_data *data,
  162.     char *units, int *array_len, int *unknown_flag);
  163.     /* see if *param was input. if it was, then fill argument list with
  164.        data from meli_datum. */
  165.  
  166. #endif /* MEL_INPUT */
  167.  
  168. /* if using MEL for output, must define the MEL output data object: */
  169. #ifdef MEL_OUTPUT
  170.  
  171. /* firstly, define output constants (all must be CUSTOMIZED): */
  172.  
  173. #define MELO_MAX_DESCRIP_STR_LEN 256
  174.     /* how many characters can be in an output descriptor string? */
  175. #define MELO_MAX_PARAMS 6
  176.     /* maximum number of parameters for any descriptor. */
  177. #define MELO_MAX_PARAM_STR_LEN 80
  178. #define MELO_MAX_PARAM_ARRAY_STR_LEN 1
  179.     /* largest allowable parameter string length. */
  180. #define MELO_MAX_PARAM_INT_ARRAY_LEN 1
  181. #define MELO_MAX_PARAM_REAL_ARRAY_LEN 1
  182. #define MELO_MAX_PARAM_STR_ARRAY_LEN 1
  183.     /* maximum number of elements in array of parameter data. */
  184. #define MELO_UNITS_STR_LEN 80
  185.     /* maximum string length of any units associated with a param. */
  186.  
  187. /* secondly, define output data structures: */
  188.  
  189. union melo_param_data {
  190.     int integer;
  191.     double real;
  192.     char string[MELO_MAX_PARAM_STR_LEN+1];
  193.     int integer_array[MELO_MAX_PARAM_INT_ARRAY_LEN];
  194.     double real_array[MELO_MAX_PARAM_REAL_ARRAY_LEN];
  195.     char string_array[MELO_MAX_PARAM_STR_ARRAY_LEN]
  196.              [MELO_MAX_PARAM_ARRAY_STR_LEN+1];
  197. };
  198. /* this is for output parameter data. it may either be an integer, real,
  199.    string, array of integers, array of reals, or an array of
  200.    strings. (to save space a union was used.) */
  201.  
  202. /* thirdly, define output variables: */
  203.  
  204. char melo_descriptor_string[MELO_MAX_DESCRIP_STR_LEN+1];
  205.     /* global storage for the output descriptor string. */
  206.  
  207. /* lastly, define output functions (typically return 0 if no error): */
  208.  
  209. int melo_init(char *descrip_type);
  210.     /* initialize private data structure (melo_datum) to accept parameter
  211.        data from following functions. output descriptor type will be
  212.        descrip_type. returns 0 if no errors were encountered. */
  213. int melo_data(char *param, union melo_param_data *data, char *units,
  214.     int array_len, int unknown_flag);
  215.     /* put data for parameter *param into the proper place in melo_datum. returns
  216.        zero if no errors were encountered. */
  217. void melo(int melo_verbose_flag);
  218.     /* takes the information in melo_datum and translates it into
  219.        melo_descriptor_string. user must set melo_verbose_flag = 1 to make
  220.        output as readable as possible, set it equal to zero to make output
  221.        as terse as possible (and still remain in MEL format). */
  222. int melo_file(FILE *melo_file_handle, int melo_verbose_flag);
  223.     /* take the information in melo_datum, translate it into
  224.        melo_descriptor_string, and output it to file. */
  225.  
  226. #endif /* MEL_OUTPUT
  227.  
  228. /* now define data objects common to both input and output: */
  229.  
  230. /* if an error occurs, MEL will try and tell you what happened. so define 
  231.    required error handling information: */
  232.  
  233. #define MEL_MAX_ERR_MSG_LEN 80
  234.  
  235. struct mel_errors {
  236.     enum {   /* which error occured? */
  237.     mel_no_err,
  238.     mel_read_err,
  239.     mel_write_err,
  240.     mel_end_of_file_err,
  241.     mel_end_of_data_err,
  242.     mel_syntax_err,
  243.     mel_unknown_descrip_name_err,
  244.     mel_unknown_param_name_err,
  245.     mel_missing_param_name_err,
  246.     mel_param_data_err,
  247.     mel_missing_paren_err,
  248.     mel_too_many_param_err,
  249.     mel_missing_bracket_err,
  250.     } type;
  251.     int start_line;   /* on which lines did err occur? */
  252.     int end_line;     /* (meaningful for input only.) */
  253.     char msg[MEL_MAX_ERR_MSG_LEN+1];   /* additional info describing err */
  254. } mel_err;                   /* (not same as messages below). */
  255.  
  256. #define MEL_MAX_NUM_ERR_MESSAGES 13
  257.  
  258. #ifdef MEL_INIT
  259.  
  260. /* the following describes each type of enumerated error: */
  261. char mel_err_msg[MEL_MAX_NUM_ERR_MESSAGES][MEL_MAX_ERR_MSG_LEN+1]
  262.     ={"No errors encountered",
  263.       "Can't read file",
  264.       "Can't write file",
  265.       "Unexpected end of file encountered",
  266.       "End of input data encountered",
  267.       "Descriptor/parameter syntax error",
  268.       "Unknown descriptor name",
  269.       "Unknown parameter name",
  270.       "A (or another) parameter name was expected but is missing",
  271.       "Unable to read parameter value(s) for this descriptor",
  272.       "Missing right parenthesis while reading units",
  273.       "Too many (or duplicate) parameters given for this descriptor",
  274.       "Missing brackets around array data"};
  275.  
  276. #else
  277.  
  278. extern char mel_err_msg[MEL_MAX_NUM_ERR_MESSAGES][MEL_MAX_ERR_MSG_LEN+1];
  279.  
  280. #endif /* MEL_INIT */
  281.  
  282. /*
  283. ------------------------------------------------------------------------
  284. "private" declarations:
  285. ------------------------------------------------------------------------
  286. */
  287.  
  288. /* hide private declarations from those routines that don't need it: */
  289. #ifdef MEL_PRIVATE
  290.  
  291. /* the possible different types of data that can be associated with a given 
  292.    descriptor's (i.e., input string's) parameters is important and is common 
  293.    to both input and output structures: */ 
  294. enum mel_data_types { 
  295.     mel_none,           /* default value */
  296.     mel_bool,           /* true or false */
  297.     mel_int,           /* integer value */
  298.     mel_real,          /* double floating point */
  299.     mel_str,           /* character string */
  300.     mel_int_array,     /* array of mel_int */
  301.     mel_real_array,    /* array of mel_real */
  302.     mel_str_array,     /* array of mel_str */
  303. };
  304.  
  305. #ifdef MEL_INPUT
  306.  
  307. /* the following structure (meli_datum) is used to store information from
  308.    the input descriptor string until the application program calls for it
  309.    via MEL. */
  310.  
  311. struct {
  312.     int start_line;
  313.     int end_line;
  314.     /* what is this descriptor's position in the input stream? 
  315.        (useful in telling user about where errors took place.) */
  316.     int descrip_type;
  317.     /* for the descriptor that was input, this is its index into
  318.        meli_descrip[] array of structures (see below). in other words,
  319.        which descriptor is it? */
  320.     int num_param;
  321.     /* number of parameters that were input. */
  322.     struct {   /* data for each parameter input */
  323.     int name_index;
  324.         /* this is the parameter's index into the meli_descrip.param[]
  325.            array, that is, which parameter is this? (see below) */
  326.     union meli_param_data data;
  327.         /* data associated with this parameter. */
  328.     char units[MELI_UNITS_STR_LEN+1];
  329.         /* what units are associated with the data? */
  330.     int array_len;
  331.         /* if the data was an array, how long was it? */
  332.     int unknown_flag;
  333.         /* is the value of this parameter "unknown"? */
  334.     } param[MELI_MAX_PARAMS];
  335. } meli_datum;
  336.  
  337. /* input dictionary manifest constants (all must be CUSTOMIZED): */
  338.  
  339. #define MELI_NUM_DESCRIP_NAMES 4
  340.     /* how many descriptors there are. */
  341. #define MELI_MAX_DESCRIP_NAME_LEN 15
  342.     /* how many characters are in the longest descriptor name? */
  343. #define MELI_MAX_PARAM_NAME_LEN 15
  344.     /* how many characters in the longest parameter name? */
  345.  
  346. /* input dictionary declaration: */
  347.  
  348. /* define the data structure used to describe MEL input data: */
  349. struct meli_descrips {   /* for each descriptor: */
  350.     char name[MELI_MAX_DESCRIP_NAME_LEN+1];   
  351.     /* descriptor's name */
  352.     int min_name_len;   
  353.     /* number of characters required to uniquely identify a 
  354.        descriptor from all others. */
  355.     int max_num_param;  
  356.     /* total number of parameters associated with this descriptor. */
  357.     struct {   /* for each parameter: */
  358.     char name[MELI_MAX_PARAM_NAME_LEN+1];   
  359.         /* parameter's name */
  360.     int min_name_len;  
  361.         /* number of characters required to uniquely this parameter 
  362.            from all others for this particular descriptor. */
  363.     enum mel_data_types type;
  364.         /* is it int, real, etc? */
  365.     } param[MELI_MAX_PARAMS];
  366. };
  367.  
  368. /* note that initialization will be required only in mel.c: */
  369. #ifdef MEL_INIT
  370.  
  371. struct meli_descrips meli_descrip[MELI_NUM_DESCRIP_NAMES] = { /* CUSTOMIZED */
  372.     {"program_data", 9, 6,
  373.        {{"program", 1, mel_str},
  374.     {"date", 1, mel_str},
  375.     {"input_filename", 1, mel_str},
  376.     {"output_filename", 1, mel_str},
  377.     {"errors_filename", 1, mel_str},
  378.     {"label", 1, mel_str}}},
  379.     {"program_options", 9, 1,
  380.        {{"output_format", 1, mel_str},
  381.     {"", 0, mel_none},
  382.     {"", 0, mel_none},
  383.     {"", 0, mel_none},
  384.     {"", 0, mel_none},
  385.     {"", 0, mel_none}}},
  386.     {"message", 1, 2,
  387.        {{"code", 1, mel_int},
  388.     {"text", 1, mel_str},
  389.     {"", 0, mel_none},
  390.     {"", 0, mel_none},
  391.     {"", 0, mel_none},
  392.     {"", 0, mel_none}}},
  393.     {"end_of_data", 1, 0,
  394.        {{"", 0, mel_none},
  395.     {"", 0, mel_none},
  396.     {"", 0, mel_none},
  397.     {"", 0, mel_none},
  398.     {"", 0, mel_none},
  399.     {"", 0, mel_none}}}};
  400.  
  401. #else
  402.  
  403. extern struct meli_descrips meli_descrip[MELI_NUM_DESCRIP_NAMES];
  404.  
  405. #endif /* MEL_INIT */
  406.  
  407. #endif /* MEL_INPUT */
  408.  
  409. #ifdef MEL_OUTPUT
  410.  
  411. /* the following structure (melo_datum) is used to store information from the
  412.    application program until output as a descriptor using MEL. */
  413.  
  414. struct {
  415.     int descrip_type;
  416.     /* for the descriptor to be output, this is its index into
  417.        melo_descrip[] array of structures (see below). in other words,
  418.        which descriptor is it? */
  419.     int num_param;
  420.     /* number of parameters to be output. */
  421.     struct {   /* data for each parameter to be output */
  422.     int name_index;
  423.         /* this is the parameter's index into the melo_descrip.param[]
  424.            array, that is, which parameter is this? (see below) */
  425.     union melo_param_data data;
  426.         /* data associated with this parameter. */
  427.     char units[MELO_UNITS_STR_LEN+1];
  428.         /* what units are associated with the data? */
  429.     int array_len;
  430.         /* if the data was an array, how long was it? */
  431.     int unknown_flag;
  432.         /* is the value of this parameter "unknown"? */
  433.     } param[MELO_MAX_PARAMS];
  434. } melo_datum;
  435.  
  436. /* output dictionary manifest constants (all must be CUSTOMIZED):*/
  437.  
  438. #define MELO_NUM_DESCRIP_NAMES 4
  439.     /* how many descriptors there are: */
  440. #define MELO_MIN_DESCRIP_NAME_LEN 9
  441.     /* how many characters does it take to uniquely define a descriptor name? */
  442. #define MELO_MAX_DESCRIP_NAME_LEN 15
  443.     /* how many characters in the longest descriptor name? */
  444. #define MELO_MIN_PARAM_NAME_LEN 1
  445.     /* how many chars to uniquely define a parameter name? */
  446. #define MELO_MAX_PARAM_NAME_LEN 15
  447.     /* how may characters in the longest parameter name? */
  448. #define MELO_MAX_DESCRIP_STR_LEN 256
  449.     /* how long may the output string be? */
  450.  
  451. /* define the data structure used to describe MEL output data: */
  452. struct melo_descrips {
  453.     char name[MELO_MAX_DESCRIP_NAME_LEN+1];
  454.     int min_name_len;
  455.     struct {
  456.     char name[MELO_MAX_PARAM_NAME_LEN+1];
  457.     int min_name_len;
  458.     enum mel_data_types type;
  459.     } param[MELO_MAX_PARAMS];
  460. };
  461.  
  462. #ifdef MEL_INIT
  463.  
  464. struct melo_descrips melo_descrip[MELO_NUM_DESCRIP_NAMES] = { /* CUSTOMIZED */
  465.     {"program_data", 9,
  466.        {{"program", 1, mel_str},
  467.     {"date", 1, mel_str},
  468.     {"input_filename", 1, mel_str},
  469.     {"output_filename", 1, mel_str},
  470.     {"errors_filename", 1, mel_str},
  471.     {"label", 1, mel_str}}},
  472.     {"program_options", 9,
  473.        {{"output_format", 1, mel_str},
  474.     {"", 0, mel_none},
  475.     {"", 0, mel_none},
  476.     {"", 0, mel_none},
  477.     {"", 0, mel_none},
  478.     {"", 0, mel_none}}},
  479.     {"message", 1,
  480.        {{"code", 1, mel_int},
  481.     {"text", 1, mel_str},
  482.     {"", 0, mel_none},
  483.     {"", 0, mel_none},
  484.     {"", 0, mel_none},
  485.     {"", 0, mel_none}}},
  486.     {"end_of_data", 1,
  487.        {{"", 0, mel_none},
  488.     {"", 0, mel_none},
  489.     {"", 0, mel_none},
  490.     {"", 0, mel_none},
  491.     {"", 0, mel_none},
  492.     {"", 0, mel_none}}}};
  493.  
  494. #else
  495.  
  496. extern struct melo_descrips melo_descrip[MELO_NUM_DESCRIP_NAMES];
  497.  
  498. #endif /* MEL_INIT */
  499.  
  500. #endif /* MEL_OUTPUT */
  501.  
  502. #endif /* MEL_PRIVATE */
  503.